﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Linq;
//
using PerceptiveMCAPI.Types.Internal;
//
namespace PerceptiveMCAPI.Types
{
   public class campaignAnalyticsOutput : Api_BaseOutput
   {
      public campaignAnalyticsResults result { get; set; }
      public campaignAnalyticsParms inputParms { get; private set; }
      // --------------------------------------------------------
      public campaignAnalyticsOutput( campaignAnalyticsInput input )
         : base( input )
      {
         inputParms = input.parms;
      }
      // --------------------------------------------------- tostring
      public override string ToString()
      {
         if ( this.result != null )
            return string.Format( "Visits: {0}", this.result.visits );
         else
            return "Results are not available";
      }

      #region ================================================================== format setup

      // ---- serial
      internal void Format( string api_Request, string api_Response )
      {
         this.api_Request = api_Request;
         this.api_Response = api_Response;
         // ----------------------------------
         if ( this.api_OutputType == EnumValues.OutputType.JSON )
            outputJSON();
         else if ( this.api_OutputType == EnumValues.OutputType.XML )
            outputXML();
      }

      // ---- xmlrpc
      internal void Format( x_campaignAnalytics rpcResult )
      {
         this.api_Request = EnumValues.NotSupplied;
         this.api_Response = EnumValues.NotSupplied;
         // ------------------------
         this.result = FormatResults( rpcResult );
      }

      #endregion

      #region ================================================================= Output

      // ---------------------------------------------------------- outputXML
      private void outputXML()
      {
         XElement xml = XElement.Parse( this.api_Response );
         // error check
         Api_Error error = apiSerial.GetXmlOutputError( xml );
         if ( error != null )
         {
            this.api_ErrorMessages.Add( error );
            return;
         }
         // -------------------------------------------- get values
         try
         {
            int it; double dbl;
            campaignAnalyticsResults result = new campaignAnalyticsResults();

            int.TryParse( xml.Element( "visits" ).Value, out it );
            result.visits = it;
            int.TryParse( xml.Element( "pages" ).Value, out it );
            result.pages = it;
            int.TryParse( xml.Element( "new_visits" ).Value, out it );
            result.new_visits = it;
            int.TryParse( xml.Element( "bounces" ).Value, out it );
            result.bounces = it;
            double.TryParse( xml.Element( "time_on_site" ).Value, out dbl );
            result.time_on_site = dbl;
            int.TryParse( xml.Element( "goal_conversions" ).Value, out it );
            result.goal_conversions = it;
            double.TryParse( xml.Element( "goal_value" ).Value, out dbl );
            result.goal_value = dbl;
            double.TryParse( xml.Element( "revenue" ).Value, out dbl );
            result.revenue = dbl;
            int.TryParse( xml.Element( "transactions" ).Value, out it );
            result.transactions = it;
            int.TryParse( xml.Element( "ecomm_conversions" ).Value, out it );
            result.ecomm_conversions = it;
            // goals -------------------------
            if ( xml.Element( "goals" ).HasElements )
            {
               IEnumerable<XElement> goals = xml.Element( "goals" ).Descendants( "struct" );
               foreach ( XElement goal in goals )
               {
                  string name = goal.Element( "name" ).Value;
                  int.TryParse( goal.Element( "conversions" ).Value, out it );
                  result.goals.Add( name, it );
               }
            }
            this.result = result;
         }
         catch ( Exception ex )
         {
            this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }
      }

      // ---------------------------------------------------------- outputJSON
      private void outputJSON()
      {
         JavaScriptSerializer jss = new JavaScriptSerializer();

         try
         {
            if ( this.api_Response.Contains( EnumValues.JSONErrorString ) )
            {
               Api_Error err = jss.Deserialize<Api_Error>( this.api_Response );
               this.api_ErrorMessages.Add( err );
            }
            else
            {
               x_campaignAnalytics jsonResult = jss.Deserialize<x_campaignAnalytics>( this.api_Response );
               this.result = FormatResults( jsonResult );
            }
         }
         catch ( Exception ex )
         {
            this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }
      }

      // ---------------------------------------------------------- FormatResults
      private campaignAnalyticsResults FormatResults( x_campaignAnalytics x_results )
      {
         campaignAnalyticsResults result = new campaignAnalyticsResults();
         result.visits = x_results.visits;
         result.pages = x_results.pages;
         result.new_visits = x_results.new_visits;
         result.bounces = x_results.bounces;
         result.time_on_site = x_results.time_on_site;
         result.goal_conversions = x_results.goal_conversions;
         result.goal_value = x_results.goal_value;
         result.revenue = x_results.revenue;
         result.transactions = x_results.transactions;
         result.ecomm_conversions = x_results.ecomm_conversions;
         // goals -----------------------------------------------
         // empty array for no values, else struct
         if ( x_results.goals == null ||
             x_results.goals.GetType().Name.ToLower() == "array" ) return result;
         //
         Array goalsArray = x_results.goals as Array;
         IEnumerator ge = goalsArray.GetEnumerator();
         while ( ge.MoveNext() )
         {
            int it;
            IDictionary goal = ge.Current as IDictionary;
            string name = goal["name"].ToString();
            int.TryParse( goal["conversions"].ToString(), out it );
            result.goals.Add( name, it );
         }
         //
         return result;
      }

      #endregion
   }
}
